using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Tokens;
using OneAuthCenter.Client.Options;

namespace OneAuthCenter.Client.Extensions;

/// <summary>
/// OneAuthCenter 客户端服务扩展方法
/// </summary>
/// <remarks>
/// 提供简化的依赖注入配置，让第三方系统轻松集成 OneAuthCenter 认证
/// 
/// 使用示例：
/// <code>
/// // Program.cs
/// builder.Services.AddOneAuthCenter(options =>
/// {
///     options.Authority = "https://auth.yourdomain.com";
///     options.Audience = "orders-api";
///     options.RequireHttpsMetadata = true;
/// });
/// 
/// // 或从配置文件读取
/// builder.Services.AddOneAuthCenter(builder.Configuration);
/// </code>
/// 
/// 配置文件示例 (appsettings.json):
/// <code>
/// {
///   "OneAuthCenter": {
///     "Authority": "https://auth.yourdomain.com",
///     "Audience": "orders-api",
///     "RequireHttpsMetadata": true
///   }
/// }
/// </code>
/// </remarks>
public static class ServiceCollectionExtensions
{
    /// <summary>
    /// 添加 OneAuthCenter JWT Bearer 认证
    /// </summary>
    /// <param name="services">服务集合</param>
    /// <param name="configureOptions">配置选项委托</param>
    /// <returns>服务集合</returns>
    public static IServiceCollection AddOneAuthCenter(
        this IServiceCollection services,
        Action<OneAuthCenterOptions> configureOptions)
    {
        var options = new OneAuthCenterOptions();
        configureOptions(options);
        
        return services.AddOneAuthCenterInternal(options);
    }
    
    /// <summary>
    /// 添加 OneAuthCenter JWT Bearer 认证（从配置读取）
    /// </summary>
    /// <param name="services">服务集合</param>
    /// <param name="configuration">配置对象</param>
    /// <param name="configurationKey">配置节点名称（默认: OneAuthCenter）</param>
    /// <returns>服务集合</returns>
    public static IServiceCollection AddOneAuthCenter(
        this IServiceCollection services,
        IConfiguration configuration,
        string configurationKey = "OneAuthCenter")
    {
        var options = new OneAuthCenterOptions();
        configuration.GetSection(configurationKey).Bind(options);
        
        return services.AddOneAuthCenterInternal(options);
    }
    
    /// <summary>
    /// 内部实现：配置 JWT Bearer 认证
    /// </summary>
    private static IServiceCollection AddOneAuthCenterInternal(
        this IServiceCollection services,
        OneAuthCenterOptions options)
    {
        // 验证必填配置
        if (string.IsNullOrWhiteSpace(options.Authority))
        {
            throw new ArgumentException("Authority 不能为空", nameof(options.Authority));
        }
        
        // 配置 HTTP 客户端（用于获取 Discovery 文档和 JWKS）
        services.AddHttpClient("OneAuthCenter", client =>
        {
            client.BaseAddress = new Uri(options.Authority);
            client.Timeout = TimeSpan.FromSeconds(options.HttpClientTimeout);
        });
        
        // 配置 JWT Bearer 认证
        services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer(jwtOptions =>
            {
                // 认证中心地址
                jwtOptions.Authority = options.Authority;
                
                // 受众验证
                if (!string.IsNullOrWhiteSpace(options.Audience))
                {
                    jwtOptions.Audience = options.Audience;
                }
                
                // HTTPS 元数据要求
                jwtOptions.RequireHttpsMetadata = options.RequireHttpsMetadata;
                
                // 是否保存 Token
                jwtOptions.SaveToken = options.SaveToken;
                
                // Token 验证参数
                jwtOptions.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuer = options.TokenValidation.ValidateIssuer,
                    ValidIssuer = options.Authority,
                    
                    ValidateAudience = options.TokenValidation.ValidateAudience,
                    ValidAudience = options.Audience,
                    
                    ValidateLifetime = options.TokenValidation.ValidateLifetime,
                    ValidateIssuerSigningKey = options.TokenValidation.ValidateIssuerSigningKey,
                    
                    ClockSkew = TimeSpan.FromSeconds(options.TokenValidation.ClockSkew)
                };
                
                // JWKS 刷新间隔
                jwtOptions.RefreshInterval = TimeSpan.FromSeconds(options.JwksRefreshInterval);
                
                // Token 验证事件
                jwtOptions.Events = new JwtBearerEvents
                {
                    OnAuthenticationFailed = context =>
                    {
                        // 记录认证失败日志
                        Console.WriteLine($"❌ JWT 认证失败: {context.Exception.Message}");
                        return Task.CompletedTask;
                    },
                    
                    OnTokenValidated = context =>
                    {
                        // Token 验证成功后的处理
                        var userId = context.Principal?.FindFirst("sub")?.Value;
                        Console.WriteLine($"✅ JWT 认证成功, 用户 ID: {userId}");
                        
                        // 如果配置了必需的 Scopes，进行验证
                        if (options.TokenValidation.RequiredScopes?.Length > 0)
                        {
                            var tokenScopes = context.Principal?.FindAll("scope")
                                .Select(c => c.Value)
                                .ToHashSet() ?? new HashSet<string>();
                            
                            var missingScopes = options.TokenValidation.RequiredScopes
                                .Where(s => !tokenScopes.Contains(s))
                                .ToList();
                            
                            if (missingScopes.Any())
                            {
                                context.Fail($"Token 缺少必需的 scopes: {string.Join(", ", missingScopes)}");
                                return Task.CompletedTask;
                            }
                        }
                        
                        return Task.CompletedTask;
                    },
                    
                    OnChallenge = context =>
                    {
                        // 返回 401 时的处理
                        Console.WriteLine($"⚠️  需要认证: {context.Error} - {context.ErrorDescription}");
                        return Task.CompletedTask;
                    }
                };
            });
        
        // 添加授权
        services.AddAuthorization();
        
        Console.WriteLine($"✅ OneAuthCenter 客户端已配置");
        Console.WriteLine($"   认证中心: {options.Authority}");
        Console.WriteLine($"   受众: {options.Audience ?? "（未设置）"}");
        Console.WriteLine($"   HTTPS 元数据: {options.RequireHttpsMetadata}");
        
        return services;
    }
    
    /// <summary>
    /// 添加 OneAuthCenter 认证（带 Scope 验证）
    /// </summary>
    /// <param name="services">服务集合</param>
    /// <param name="authority">认证中心地址</param>
    /// <param name="audience">API 资源标识符</param>
    /// <param name="requiredScopes">必需的 Scopes</param>
    /// <returns>服务集合</returns>
    public static IServiceCollection AddOneAuthCenter(
        this IServiceCollection services,
        string authority,
        string audience,
        params string[] requiredScopes)
    {
        return services.AddOneAuthCenter(options =>
        {
            options.Authority = authority;
            options.Audience = audience;
            options.TokenValidation.RequiredScopes = requiredScopes;
        });
    }
}

